package com.xdf.whiteaccount.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xdf.whiteaccount.entity.ResponseResult;
import com.xdf.whiteaccount.utils.WebUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.dao.DataAccessException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: xzy-management-system
 * @description: 全局异常处理
 * @author: 张柯
 * @create: 2020-12-31 09:01
 **/
@ControllerAdvice
@Slf4j
public class GlobalController {
    private static final String ERROR_01 = "a foreign key constraint fails";

    /**
     * 外键约束
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = DataAccessException.class)
    @ResponseBody
    public ResponseResult<Void> SQLIntegrityConstraintViolationExceptionHandler(SQLIntegrityConstraintViolationException e) {
        log.error(e.getMessage());
        String msg = "名称或编号等重复!";
        e.printStackTrace();
        if (e.getMessage() != null && e.getMessage().contains(ERROR_01)) {
            msg = "有关联单据,禁止修改或删除!";
        }
        return ResponseResult.<Void>builder()
                .success(false)
                .responseCode("500")
                .message(msg)
                .build();
    }

    /**
     * 无权限返回页面或者json字符串
     *
     * @param e
     * @return
     */
    @ExceptionHandler({UnauthorizedException.class, AuthorizationException.class})
    public Object AuthorizationExc(HttpServletRequest request, HttpServletResponse response, Exception e) {
        if (WebUtil.isAjaxRequest(request)) {
            ResponseResult rr = ResponseResult.<Void>builder()
                    .success(false)
                    .responseCode("500")
                    .message("本功能无权操作!")
                    .build();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json;charset=UTF-8");
            try {
                String json = String.valueOf(new JSONObject(new ObjectMapper().writeValueAsString(rr)));
                response.getWriter().write(json);
            } catch (Exception ioException) {
                log.error(ioException.getMessage());
            }
            return null;
        }
        return "redirect:/unauthorized";
    }

    /**
     * 服务器内部错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseResult<Void> exceptionHandler(Exception e) {
        log.error(e.getMessage());
        e.printStackTrace();
        return ResponseResult.<Void>builder()
                .success(false)
                .responseCode("500")
                .message(e.getMessage())
                .build();
    }

    /**
     * 校验异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public ResponseResult<Void> handleBindException(BindException e) {
        List<FieldError> errors = e.getFieldErrors();
        String errMsg = errors.stream().map(FieldError::getDefaultMessage).collect(Collectors.joining("\n"));
        return ResponseResult.<Void>builder().success(false).message(errMsg).build();
    }
}